//----------------------------------------------------------------------------
//  ,-.
// /_\___ ,   Ninja Framework
// '  ___\    (C) Riccardo Capra - http://riccar.do
//  //   \\
//----------------------------------------------------------------------------
//  This program is free software: you can redistribute it and/or modify
//  it under the terms of the GNU General Public License as published by
//  the Free Software Foundation, either version 3 of the License, or
//  (at your option) any later version.
//
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU General Public License for more details.
//
//  You should have received a copy of the GNU General Public License
//  along with this program.  If not, see <http://www.gnu.org/licenses/>.
//----------------------------------------------------------------------------

#ifndef NJ_RW_LOCK_INLINE_H
#	define NJ_RW_LOCK_INLINE_H

	//----------------------------------------------------------------------------
	inline void NjRWLock::Read::Lock()
	{
		GetRWLock().LockRead();
	}
	//----------------------------------------------------------------------------
	inline NjBool NjRWLock::Read::TryLock(TimeMs uTimeMs)
	{
		return GetRWLock().TryLockRead(uTimeMs);
	}
	//----------------------------------------------------------------------------
	inline void NjRWLock::Read::Unlock()
	{
		GetRWLock().UnlockRead();
	}
	//----------------------------------------------------------------------------
	inline NjRWLock & NjRWLock::Read::GetRWLock()
	{
		return *reinterpret_cast<NjRWLock *>(this);
	}
	//----------------------------------------------------------------------------
	inline void NjRWLock::Write::Lock()
	{
		GetRWLock().LockWrite();
	}
	//----------------------------------------------------------------------------
	inline NjBool NjRWLock::Write::TryLock(TimeMs uTimeMs)
	{
		return GetRWLock().TryLockWrite(uTimeMs);
	}
	//----------------------------------------------------------------------------
	inline void NjRWLock::Write::Unlock()
	{
		GetRWLock().UnlockWrite();
	}
	//----------------------------------------------------------------------------
	inline NjRWLock & NjRWLock::Write::GetRWLock()
	{
		return *reinterpret_cast<NjRWLock *>(this);
	}
	//----------------------------------------------------------------------------
	inline NjRWLock::NjRWLock()
	:
		m_kState(0),
		m_kReadEvent(0),
		m_kWriteEvent(0)
#	if NJ_RW_LOCK_STORE_WRITE_LOCKER_ENABLED
		, m_kThreadDebugIdWrite(NjEventsSystem::INVALID_THREAD_ID)
#	endif // NJ_RW_LOCK_STORE_WRITE_LOCKER_ENABLED
#	if NJ_RW_LOCK_STORE_USERS_ENABLED
		, m_kUsers(0)
#	endif // NJ_RW_LOCK_STORE_USERS_ENABLED
	{
	}
	//----------------------------------------------------------------------------
	inline void NjRWLock::LockRead()
	{
#	if NJ_ASSERT_ENABLED
		NjBool bSuccess=
#	endif // NJ_ASSERT_ENABLED

		TryLockRead(NjEventsSystem::WAIT_FOREVER);

		NJ_ASSERT(bSuccess);
	}
	//----------------------------------------------------------------------------
	inline void NjRWLock::LockWrite()
	{
#	if NJ_ASSERT_ENABLED
		NjBool bSuccess=
#	endif // NJ_ASSERT_ENABLED

		TryLockWrite(NjEventsSystem::WAIT_FOREVER);

		NJ_ASSERT(bSuccess);
	}
	//----------------------------------------------------------------------------
	inline void NjRWLock::UnlockWrite()
	{
		UnlockWriteInternal(NJ_FALSE);
	}
	//----------------------------------------------------------------------------
	inline NjRWLock::Read & NjRWLock::GetRead()
	{
		return *reinterpret_cast<Read *>(this);
	}
	//----------------------------------------------------------------------------
	inline NjRWLock::Write & NjRWLock::GetWrite()
	{
		return *reinterpret_cast<Write *>(this);
	}
	//----------------------------------------------------------------------------

#endif // NJ_RW_LOCK_INLINE_H
